package com.example.martian.service;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.example.martian.config.util.RedisUtils;
import com.example.martian.mapper.CustodyMapper;
import com.example.martian.mapper.IndexMapper;
import com.example.martian.mapper.RedPacketMapper;
import com.example.martian.utils.*;
import com.sun.org.apache.bcel.internal.generic.IF_ACMPEQ;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.io.IOException;
import java.math.BigDecimal;
import java.text.SimpleDateFormat;
import java.util.HashMap;
import java.util.List;
import java.util.Map;


@Service
@Transactional(rollbackFor = Exception.class)
public class CustodyService{

    @Autowired
    private CustodyMapper custodyMapper;

    @Autowired
    private RedisUtils redisUtils;

    @Autowired
    private CustodyUtils custodyUtils;

    @Autowired
    private ExchangeRateUtils exchangeRateUtils;

    @Autowired
    private RedPacketMapper redPacketMapper;

    @Autowired
    private IndexMapper indexMapper;

    private static final String URL = "http://api.tianapi.com/txapi/fxrate/index?key=0d9d342a93446f794927f8100d164632&" +
            "fromcoin=USD&tocoin=CNY&money=1";

    @Transactional
    public Object testApi() throws Exception {
       Custody.testApi();
       return null;
    }

    //划转
    @Transactional(rollbackFor = Exception.class)
    public Object transfer(String address,String fromAddressKey,String toAddressKey,
                           String coin,String value,Integer type) throws Exception {
        //查询被划转账户余额
        String coinMoney = custodyMapper.selectCoinMoneyByCoin(fromAddressKey);
        //查询划转账户余额
        String moneyByCoin = custodyMapper.selectCoinMoneyByMiningCoin(toAddressKey);
        if (new BigDecimal(value).compareTo(BigDecimal.ZERO) == -1) {
            return Utils.toJSON("非法数量", Utils.toJSONmap(), "1");
        }
        Boolean info = Custody.address_info(coin, toAddressKey);
//        if (!info){
//            return Utils.toJSON("地址不合法",Utils.toJSONmap(),"3");
//        }
        coin = coin.toUpperCase();
        if (coin.equals("USDT")){
            coin = "ETH"+"_"+"USDT";
        }
        if (type == 1){
            boolean compare = BigDecimalUtils.compare(value,coinMoney);
            if (compare){
                return Utils.toJSON("可用余额不足", Utils.toJSONmap(), "2");
            }
        }else if (type == 2){
            boolean compare = BigDecimalUtils.compare(value, moneyByCoin);
            if (compare){
                return Utils.toJSON("可用余额不足", Utils.toJSONmap(), "2");
            }
        }else {
            return Utils.toJSON("参数不正确", Utils.toJSONmap(), "3");
        }
        String uuid = String.valueOf(System.currentTimeMillis());
        String amount = String.valueOf(BigDecimalUtils.mul(Double.parseDouble(value),1e18));
        Custody.getCoinWithdraw(coin, toAddressKey,amount,uuid);
        Map<String, Object> transferList = custodyUtils.getTransferList(uuid, address);
        if (transferList.get("success").toString().equals("false")){
            JSONObject jsonObject = new JSONObject();
            Object error_code = transferList.get("error_code");
            jsonObject.put("error_code",error_code);
            return Utils.toJSON("划转失败，请联系客服",jsonObject.toString(),"4");
        }
        String create_time = transferList.get("create_time").toString();
        String side = "trading";
        String status = transferList.get("status").toString();
        //计算提现
        String sub = BigDecimalUtils.sub(coinMoney, value, 8);
        //计算划转
        String add = BigDecimalUtils.add(value, moneyByCoin,8);
        //更新金额
        custodyMapper.updateCoinMoneyByAddressAndCoin(sub,fromAddressKey);
        custodyMapper.updateCoinMoneyByAddressAndMiningCoin(add,toAddressKey);
        redisUtils.setDataToCache(address+uuid,uuid);
        if (coin.equals("TETH")){
            coin = "ETH";
        }
        custodyUtils.addTopUp(address,create_time,coin,value,side,status,fromAddressKey,toAddressKey,uuid,type);
        return Utils.toJSON("划转成功",Utils.toJSONmap(),"0");
    }


    //查询用户到账信息
    @Scheduled(cron = "0/10 * * * * ?")
    @Transactional(rollbackFor = Exception.class)
    public void transaction_history(){
        Integer type = 0;
        String coboId = "";
        String uuid = Utils.getRandom(10);
        SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd  HH:mm:ss");
        List<Map<String, Object>> maps = custodyMapper.selectAddressKeyAll();
        try{
                String min_id = redisUtils.getDataFromCache("coboId").toString();
                JSONObject transactionHistory = Custody.transaction_history(min_id);
                JSONArray result = transactionHistory.getJSONArray("result");
                if (result.size() == 0){
                    transaction_history();
                }else {
                    for (int fla = 0;fla < result.size();fla++){
                        JSONObject resultObj = (JSONObject) result.get(fla);
                        for (Map<String,Object> map : maps){
                            if (String.valueOf(map.get("cmc_addressKey")).equals(resultObj.get("address"))){
                                Map<String,Object> param = new HashMap<>();
                                String addressKey = resultObj.get("address").toString();
                                String create_time = dateFormat.format(BigDecimalUtils.mul(String.valueOf(resultObj.get("created_time")), String.valueOf(1000)));
                                String coin = resultObj.get("coin").toString();
                                if (coin.equals("TETH")){
                                    coin = "ETH";
                                }
                                String value =  new BigDecimal(resultObj.getBigDecimal("amount").
                                        divide(BigDecimal.valueOf(1e18), 10, BigDecimal.ROUND_HALF_EVEN).toPlainString()).toString();
                                String side = resultObj.get("side").toString();
                                String status = resultObj.get("status").toString();
                                String toAddress = resultObj.get("address").toString();
                                String fromAddress = resultObj.get("source_address").toString() ;
                                param.put("created_time",create_time);//交易时间
                                param.put("coin",coin);//交易币种
                                param.put("value",value);//交易金额
                                param.put("side",side);//交易规则  deposit 充值 / withdraw 提现
                                param.put("status",status);//状态  是否成功
                                param.put("toAddress",toAddress);//充值地址
                                param.put("fromAddress",fromAddress);//源地址
                                coboId = resultObj.get("id").toString();
                                String moneyByCoin = custodyMapper.selectCoinMoneyByCoin(addressKey);
                                String address = custodyMapper.selectAddressByAddressKey(addressKey);
                                //更改金额
                                if (side.equals("deposit")){
                                    String coinMoney = String.valueOf(new BigDecimal(moneyByCoin).add(BigDecimal.valueOf(Double.parseDouble(value))));
                                    custodyMapper.updateCoinMoneyByAddressAndCoin(coinMoney,addressKey);
                                    custodyUtils.addTopUp(address,create_time,coin,value,side,status,fromAddress,toAddress,uuid,type);
                                }
                                redisUtils.setDataToCache("coboId",coboId);
                            }
                        }
                    }
                }
        } catch (Exception e){
            e.printStackTrace();
            System.out.println("");
        }
    }

    //查询账户信息
    @Transactional(rollbackFor = Exception.class)
    public Object checkWellatMine() throws Exception {
        JSONObject jsonObject = Custody.checkWellatMine();
        return Utils.toJSON("访问成功",jsonObject.toString(),"0");
    }

    //钱包展示
    @Transactional(rollbackFor = Exception.class)
    public Object selectWellatByCoinFlash(String address) throws IOException {
        String exchange = "";
//        JSONObject jsonObj = exchangeRateUtils.exchangeRate(URL);
//        JSONObject obj = jsonObj.getJSONArray("newslist").getJSONObject(0);
        String money = "6.61";
        JSONObject jsonObject = null;
        JSONObject object = null;
        JSONArray jsonArray = new JSONArray();
        List<Map<String, Object>> maps = null;
        maps = custodyMapper.selectWellatByCoinFlash(address);
        for (Map<String,Object> map : maps){
            jsonObject = new JSONObject();
            String coinMoney = map.get("money").toString();
            String cmcCoin = map.get("coin").toString();
            jsonObject.put("addressKey",map.get("addressKey"));
            if (map.get("addressKey") == null){

            }else {
                if (cmcCoin.equals("ETH_USDT")){
                    cmcCoin = "USDT";
                    exchange = exchangeRateUtils.exchange(cmcCoin);
                }else {
                    exchange = exchangeRateUtils.exchange(cmcCoin);
                }
                String CNY = BigDecimalUtils.mul(exchange, money, 8);
                jsonObject.put("coin",cmcCoin);
                jsonObject.put("withdraw_service",map.get("withdraw_service"));
                jsonObject.put("balance",map.get("money"));
                jsonObject.put("validMoney",map.get("validMoney"));
                jsonObject.put("freezeMoney",map.get("freezeMoney"));
                jsonObject.put("logo",map.get("logo"));
                jsonObject.put("CNY",CNY);
                String balanceCNY = new BigDecimal(CNY).multiply(new BigDecimal(coinMoney)).stripTrailingZeros().toPlainString();
                jsonObject.put("balanceCNY",balanceCNY);
            }
            jsonArray.add(jsonObject);
        }
        return Utils.toJSON("访问成功",jsonArray.toString(),"0");
    }

    //提现
    @Transactional(rollbackFor = Exception.class)
    public Object coinWithdraw(String address,String addressKey,String toAddress,String coin,
                                   String withdraw_service,String value,String comment,Integer jypassword) throws Exception {
        if(coin.equals("USDT")){
            coin = "ETH_USDT";
        }
        if (new BigDecimal(value).compareTo(BigDecimal.ZERO) == -1) {
            return Utils.toJSON("非法数量", Utils.toJSONmap(), "1");
        }

        String coinMoney = custodyMapper.selectCoinMoneyByCoin(addressKey);
        Integer jYpassword = redPacketMapper.selectJYpassword(address);
        System.out.println("2222222222222222222222222222222");
        if (BigDecimalUtils.compare(value,coinMoney)){
            return Utils.toJSON("可用余额不足", Utils.toJSONmap(), "2");
        }
        if (!(jypassword.equals(jYpassword))) {
            return Utils.toJSON("交易密码错误，请重新输入", null, "3");
        }
        String uuid = String.valueOf(System.currentTimeMillis());
        String amount = new BigDecimal(value).multiply(new BigDecimal(1e18)).stripTrailingZeros().toPlainString();
        Custody.getCoinWithdraw(coin, toAddress,amount, uuid);
        System.out.println("44444444444444444444444444444");
        boolean recordList = custodyUtils.getRecordList(uuid, address);
        if (!recordList){
            JSONObject jsonObject = new JSONObject();
            jsonObject.put("error_code",12006);
            return Utils.toJSON("提现失败，请联系客服",jsonObject.toString(),"4");
        }
        //计算提现
        String sub = BigDecimalUtils.sub(coinMoney, value, 8);
        String mul = BigDecimalUtils.mul(sub, withdraw_service, 8);
        //更新金额
        custodyMapper.updateCoinMoneyByAddressAndCoin(mul,addressKey);
        redisUtils.setDataToCache(address+uuid,uuid);
        return Utils.toJSON("提现成功",Utils.toJSONmap(),"0");
    }

    //USDT流水记录
    @Transactional(rollbackFor = Exception.class)
    public Object selectUsdtRecord(String address,String coin) throws Exception {
//        JSONObject jsonObject = exchangeRateUtils.exchangeRate(URL);
//        JSONObject object = jsonObject.getJSONArray("newslist").getJSONObject(0);
        if (coin.equals("USDT")){
            coin = "ETH_USDT";
        }
        String moneyByCoin = indexMapper.selectMoneyByCoin(coin, address);
        String money = "6.61";
        String CNY = BigDecimalUtils.mul(moneyByCoin, money, 4);
        JSONObject objectList = null;
        JSONArray jsonArray = new JSONArray();
        Map<String,Object> zt = new HashMap<>();
        List<Map<String, Object>> list = custodyMapper.selectTransactionId(address);
        for (Map<String, Object> map : list){
            String uuidRedis = map.get("cmc_uuid").toString();
            String uuid = address + uuidRedis;
            boolean exists = redisUtils.exists(uuid);
            if (exists){
                String  dataUuid = redisUtils.getDataFromCache(uuid).toString();
                JSONObject withdrawInfoByRequestId = Custody.withdraw_info_by_request_id(dataUuid);
                JSONObject jsonArrayResult = withdrawInfoByRequestId.getJSONObject("result");
                String status = jsonArrayResult.get("status").toString();
                custodyMapper.updateStatus(status,uuidRedis);
                if (status.equals("success")){
                    redisUtils.clearCache(uuid);
                }else if (status.equals("failed ")){
                    String value =  new BigDecimal(jsonArrayResult.getBigDecimal("amount").
                                divide(BigDecimal.valueOf(1e18), 10, BigDecimal.ROUND_HALF_EVEN).toPlainString()).toString();
                    String addressKey = jsonArrayResult.get("source_address").toString();
                    String moneyCoin = custodyMapper.selectCoinMoneyByCoin(addressKey);
                    String addMoney = BigDecimalUtils.add(value, moneyCoin, 8);
                    custodyMapper.updateCoinMoney(addMoney,addressKey);
                    custodyMapper.updateCoinMoneyByMining(addMoney,addressKey);
                }
            }
        }
        List<Map<String, Object>> mapList = custodyMapper.selectUsdtRecord(address, coin);
        List<Map<String, Object>> maps = custodyMapper.selectUsdtMoneyZt(address, coin);
        for (Map<String,Object> map : maps) {
            for (Map<String, Object> mapObj : mapList) {
                objectList = new JSONObject();
                objectList.put("CNY", CNY);
                objectList.put("money",map.get("cmc_money"));
                objectList.put("validMoney",map.get("cmc_validMoney"));//可用
                objectList.put("freezeMoney",map.get("cmc_freezeMoney"));//冻结
                objectList.put("side", mapObj.get("cmc_side"));
                objectList.put("status", mapObj.get("cmc_status"));
                objectList.put("value", mapObj.get("cmc_value"));
                objectList.put("create_time", mapObj.get("cmc_create_time"));
                objectList.put("type", mapObj.get("cmc_type"));
                jsonArray.add(objectList);
            }
        }
        return Utils.toJSON("访问成功",jsonArray.toString(),"0");
    }

    //挖矿账户收益展示
    @Transactional(rollbackFor = Exception.class)
    public Object checkMiningEarnings(String address,Integer type){
        BigDecimal money = BigDecimal.valueOf(6.61);
        JSONObject object = null;
        String coin = "";
        if (type == 1){
            coin = "BTC";
        }
        if (type == 2){
            coin = "ETH";
        }
        String exchange = exchangeRateUtils.exchange(coin);
        JSONArray jsonArray = new JSONArray();
        List<Map<String, Object>> mapList = custodyMapper.checkEarningsByCoin(address,type);
        if (type == 3){
            return Utils.toJSON("参数错误",jsonArray.toString(),"1");
        }
        for (Map<String,Object> map : mapList){
            object = new JSONObject();
            String CNY = BigDecimalUtils.mul(exchange, String.valueOf(0), 8);
//            new BigDecimal(exchange).multiply(money).multiply()
            object.put("sumEarnings",0);
            object.put("earningsCny",CNY);
            object.put("validMoney",0);
            object.put("yesterdayEarnings","0");
            object.put("subarea",map.get("cmc_subarea"));
            object.put("earnings",map.get("cmc_earnings"));
            object.put("countEarnings","0");
            object.put("calidEarnings","0");
            jsonArray.add(object);
        }
        return Utils.toJSON("访问成功",jsonArray.toString(),"0");
    }

    //根据币种和地址查询收益
    @Transactional(rollbackFor = Exception.class)
    public Object selectHashrateByAddressAndCoin(String address,Integer type){
        JSONObject object = null;
        JSONArray jsonArray = new JSONArray();
        List<Map<String, Object>> mapList = custodyMapper.selectHashrateByAddressAndCoin(address, type);
        for (Map<String,Object> map : mapList){
            object = new JSONObject();
            object.put("subarea",map.get("subarea"));
            object.put("createTime",map.get("createTime"));
            object.put("hashrate",map.get("hashrate"));
            object.put("addMoney",map.get("addMoney"));
            jsonArray.add(object);
        }
        return Utils.toJSON("访问成功",jsonArray.toString(),"0");
    }

    @Transactional(rollbackFor = Exception.class)
    public Object exchangeCustody(){
        return null;
    }

}
